package PrjWsMQ

import (
	"dgo/goutils/utils"
	"strings"

	"golang.org/x/net/websocket"
)

type WsSvrConn struct {
	channelMap utils.GSyncMapGroup
	owner      *WsMQServer
	conn       *WsConnEx
	remoteAddr string
}

func NewWsSvrConn(conn *websocket.Conn, owner *WsMQServer) *WsSvrConn {
	rval := &WsSvrConn{
		conn:  WrapperWsConnEx(conn),
		owner: owner,
	}
	rval.remoteAddr = conn.RemoteAddr().String()
	return rval
}

func (this *WsSvrConn) RemoteAddr() string {
	conn := this.conn
	if conn != nil && conn.Request() != nil {
		return conn.Request().RemoteAddr
	} else {
		return this.remoteAddr
	}
}

/*
**

	收到订阅通道的数据,进行发送
*/
func (this *WsSvrConn) onChannelRecv(sender interface{}, channelid string, subscribeid interface{}, data interface{}, tag interface{}, isBreak *bool) bool {
	if str, ok := data.(string); ok {
		SendWsMessage(this.conn, WS_MESSAGE_TEXT, []byte(str))
	} else if buf, ok := data.([]byte); ok {
		SendWsMessage(this.conn, WS_MESSAGE_BINARY, buf)
	}
	return true
}

func (this *WsSvrConn) onClose() {
	this.channelMap.Range(func(key, value interface{}) bool {
		channelid := key.(string)
		this.owner.sc.UnsubscribeChannel(channelid, value.(string))
		return true
	})
	golog.Debugf("[断线][%s]", this.remoteAddr)
	this.conn = nil
}

func (this *WsSvrConn) SubscribleChannel(channels string) {
	strs := strings.Split(channels, ",")
	for _, str := range strs {
		channelid := utils.Trim(str)
		if len(channelid) == 0 {
			continue
		}
		itm := this.channelMap.Get(channelid, nil)
		if itm == nil {
			// 订阅中心的ID
			id := utils.RandHexString(24)
			golog.Debugf("[订阅]通道:[%s], %s", channelid, this.RemoteAddr())
			this.owner.sc.SubscribeChannel(channelid, id, this.onChannelRecv)

			// 保存订阅中心的ID,便于取消订阅
			this.channelMap.Set(channelid, id)
		}
	}
}

func (this *WsSvrConn) UnsubscribleChannel(channels string) {
	strs := strings.Split(channels, ",")
	for _, str := range strs {
		channelid := utils.Trim(str)
		if len(channelid) == 0 {
			continue
		}
		subid := this.channelMap.Get(channelid, nil)
		if subid != nil {
			golog.Debugf("[订阅]通道:[%s], %s", channelid, this.remoteAddr)

			str := subid.(string)

			this.owner.sc.UnsubscribeChannel(channelid, str)

			// 该通道没有订阅该channel
			this.channelMap.Remove(channelid)
		}
	}
}
